﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using DocumentFormat.OpenXml.Packaging;

namespace DocFormatModi
{
    /// <summary>
    /// 文档格式合并对话框
    /// 用于选择Word模板和多个Word文档，将模板的格式应用到选中的文档并合并
    /// </summary>
    public partial class MergeDocDialog : Form
    {
        /// <summary>
        /// 存储模板文件名和完整路径的映射关系
        /// Key: 模板文件名
        /// Value: 模板文件的完整路径
        /// </summary>
        private Dictionary<string, string> templatePathMap = new Dictionary<string, string>();

        /// <summary>
        /// 存储选中的Word文档路径列表
        /// </summary>
        private List<string> selectedWordFiles = new List<string>();

        /// <summary>
        /// 用于存储表格中每行文档的详细信息的类
        /// </summary>
        private class WordDocumentInfo
        {
            public bool IsSelected { get; set; }      // 是否被选中
            public string FileName { get; set; }      // 文件名（包含后缀）
            public string FullPath { get; set; }      // 文件完整路径
            public int PageCount { get; set; }        // 文档页数
        }

        /// <summary>
        /// 存储所有导入的Word文档信息的列表
        /// </summary>
        private List<WordDocumentInfo> m_wordDocuments = new List<WordDocumentInfo>();

        /// <summary>
        /// 单例实例，确保整个应用程序中只有一个对话框实例
        /// </summary>
        private static MergeDocDialog _instance;

        /// <summary>
        /// 用于线程安全的锁对象
        /// </summary>
        private static readonly object _lock = new object();

        /// <summary>
        /// 构造函数
        /// 初始化组件并加载默认模板
        /// </summary>
        public MergeDocDialog()
        {
            InitializeComponent();
            InitTemplateDoc();
        }

        /// <summary>
        /// 获取单例实例的属性
        /// 确保整个应用程序中只有一个对话框实例
        /// </summary>
        public static MergeDocDialog Instance
        {
            get
            {
                if (_instance == null)
                {
                    lock (_lock) // 确保线程安全
                    {
                        if (_instance == null)
                        {
                            _instance = new MergeDocDialog();
                        }
                    }
                }
                return _instance;
            }
        }

        /// <summary>
        /// 初始化模板文档
        /// 加载程序目录下的所有.dotx模板文件（除CLGRTEMP外）
        /// </summary>
        private void InitTemplateDoc()
        {
            // 清空现有的映射关系和下拉框
            templatePathMap.Clear();
            m_comboBox1.Items.Clear();

            // 获取程序目录下的默认模板
            string appPath = Path.GetDirectoryName(Application.ExecutablePath);
            if (appPath != null)
            {
                foreach (string file in Directory.GetFiles(appPath, "*.dotx"))
                {
                    string fileName = Path.GetFileName(file);
                    // 跳过 CLGRTEMP 模板
                    if (!fileName.Contains("CLGRTEMP"))
                    {
                        templatePathMap[fileName] = file;
                        m_comboBox1.Items.Add(fileName);
                    }
                }
            }
        }

        /// <summary>
        /// 选择Word模板按钮点击事件处理
        /// 打开文件选择对话框，允许用户选择多个.dotx模板文件
        /// </summary>
        private void button4_Click(object sender, EventArgs e)
        {
            try
            {
                using (OpenFileDialog openFileDialog = new OpenFileDialog())
                {
                    // 配置文件选择对话框
                    openFileDialog.Filter = "Word模板(*.dotx)|*.dotx";
                    openFileDialog.Title = "选择Word模板";
                    openFileDialog.Multiselect = true;
                    openFileDialog.RestoreDirectory = true;

                    if (openFileDialog.ShowDialog() == DialogResult.OK)
                    {
                        // 清空现有的模板
                        templatePathMap.Clear();
                        m_comboBox1.Items.Clear();

                        // 添加新选择的模板
                        foreach (string filePath in openFileDialog.FileNames)
                        {
                            string fileName = Path.GetFileName(filePath);
                            
                            // 跳过 CLGRTEMP 模板
                            if (!fileName.Contains("CLGRTEMP"))
                            {
                                templatePathMap[fileName] = filePath;
                                m_comboBox1.Items.Add(fileName);
                            }
                        }

                        // 如果有模板，选择第一项
                        if (m_comboBox1.Items.Count > 0)
                        {
                            m_comboBox1.SelectedIndex = 0;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"选择Word模板时发生错误：{ex.Message}",
                               "错误",
                               MessageBoxButtons.OK,
                               MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 导入Word文档按钮点击事件处理
        /// 打开文件选择对话框，允许用户选择多个Word文档
        /// </summary>
        private void button2_Click_1(object sender, EventArgs e)
        {
            try
            {
                using (OpenFileDialog openFileDialog = new OpenFileDialog())
                {
                    // 配置文件选择对话框
                    openFileDialog.Filter = "Word文档(*.docx;*.doc)|*.docx;*.doc";
                    openFileDialog.Title = "选择Word文档";
                    openFileDialog.Multiselect = true;
                    openFileDialog.RestoreDirectory = true;

                    if (openFileDialog.ShowDialog() == DialogResult.OK)
                    {
                        m_wordDocuments.Clear();
                        foreach (string filePath in openFileDialog.FileNames)
                        {
                            m_wordDocuments.Add(new WordDocumentInfo
                            {
                                IsSelected = false,
                                FileName = Path.GetFileName(filePath),
                                FullPath = filePath,
                                PageCount = 0
                            });
                        }

                        InitializeDataGridView();
                        LoadPageCounts();
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"选择Word文档时发生错误：{ex.Message}",
                               "错误",
                               MessageBoxButtons.OK,
                               MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 加载所有文档的页数
        /// 遍历文档列表，获取每个文档的页数并更新到表格中
        /// </summary>
        private void LoadPageCounts()
        {
            foreach (var doc in m_wordDocuments)
            {
                doc.PageCount = GetWordDocumentPageCount(doc.FullPath);
                foreach (DataGridViewRow row in dataGridView1.Rows)
                {
                    if (row.Cells["FileName"].Value.ToString() == doc.FileName)
                    {
                        row.Cells["PageCount"].Value = doc.PageCount;
                    }
                }
            }
        }

        /// <summary>
        /// 自定义的复选框表头单元格类
        /// 用于实现表格顶部的全选/取消全选功能
        /// </summary>
        private class DataGridViewCheckBoxHeaderCell : DataGridViewColumnHeaderCell
        {
            private bool isChecked = false;
            public bool Checked
            {
                get { return isChecked; }
                set { isChecked = value; }
            }

            /// <summary>
            /// 重写Paint方法，自定义绘制表头复选框
            /// </summary>
            protected override void Paint(Graphics graphics,
                                      Rectangle clipBounds,
                                      Rectangle cellBounds,
                                      int rowIndex,
                                      DataGridViewElementStates dataGridViewElementState,
                                      object value,
                                      object formattedValue,
                                      string errorText,
                                      DataGridViewCellStyle cellStyle,
                                      DataGridViewAdvancedBorderStyle advancedBorderStyle,
                                      DataGridViewPaintParts paintParts)
            {
                // 绘制背景
                using (Brush backBrush = new SolidBrush(cellStyle.BackColor))
                {
                    graphics.FillRectangle(backBrush, cellBounds);
                }
                
                // 绘制边框
                using (Pen borderPen = new Pen(this.DataGridView.GridColor))
                {
                    graphics.DrawRectangle(borderPen, cellBounds.X, cellBounds.Y, 
                                         cellBounds.Width - 1, cellBounds.Height - 1);
                }

                // 计算复选框的位置
                int checkBoxSize = 15;
                Point checkBoxLocation = new Point(
                    cellBounds.X + (cellBounds.Width - checkBoxSize) / 2,
                    cellBounds.Y + (cellBounds.Height - checkBoxSize) / 2
                );
                Rectangle checkBoxRect = new Rectangle(checkBoxLocation, new Size(checkBoxSize, checkBoxSize));

                // 绘制复选框
                ButtonState state = isChecked ? ButtonState.Checked : ButtonState.Normal;
                ControlPaint.DrawCheckBox(graphics, checkBoxRect, state);
            }
        }

        /// <summary>
        /// 初始化DataGridView表格
        /// 设置列、绑定数据源、配置表格属性
        /// </summary>
        private void InitializeDataGridView()
        {
            try
            {
                // 清空现有数据和列
                dataGridView1.DataSource = null;
                dataGridView1.Columns.Clear();
                dataGridView1.AutoGenerateColumns = false;

                // 添加复选框列
                DataGridViewCheckBoxColumn checkBoxColumn = new DataGridViewCheckBoxColumn();
                checkBoxColumn.HeaderText = string.Empty;
                checkBoxColumn.Name = "IsSelected";
                checkBoxColumn.DataPropertyName = "IsSelected";
                checkBoxColumn.Width = 50;
                checkBoxColumn.HeaderCell = new DataGridViewCheckBoxHeaderCell();
                dataGridView1.Columns.Add(checkBoxColumn);

                // 添加文件名列
                DataGridViewTextBoxColumn fileNameColumn = new DataGridViewTextBoxColumn();
                fileNameColumn.HeaderText = "文档名称";
                fileNameColumn.Name = "FileName";
                fileNameColumn.DataPropertyName = "FileName";
                fileNameColumn.Width = 300;
                fileNameColumn.ReadOnly = true;
                dataGridView1.Columns.Add(fileNameColumn);

                // 添加页数列
                DataGridViewTextBoxColumn pageCountColumn = new DataGridViewTextBoxColumn();
                pageCountColumn.HeaderText = "页数";
                pageCountColumn.Name = "PageCount";
                pageCountColumn.DataPropertyName = "PageCount";
                pageCountColumn.Width = 100;
                pageCountColumn.ReadOnly = true;
                dataGridView1.Columns.Add(pageCountColumn);

                // 添加预览按钮列
                DataGridViewButtonColumn previewColumn = new DataGridViewButtonColumn();
                previewColumn.HeaderText = "预览";
                previewColumn.Name = "preview";
                previewColumn.Text = "预览";
                previewColumn.UseColumnTextForButtonValue = true;
                previewColumn.Width = 80;
                dataGridView1.Columns.Add(previewColumn);

                // 添加删除按钮列
                DataGridViewButtonColumn deleteColumn = new DataGridViewButtonColumn();
                deleteColumn.HeaderText = "删除";
                deleteColumn.Name = "delete";
                deleteColumn.Text = "删除";
                deleteColumn.UseColumnTextForButtonValue = true;
                deleteColumn.Width = 80;
                dataGridView1.Columns.Add(deleteColumn);

                // 设置数据绑定和表格属性
                dataGridView1.DataSource = new BindingSource(m_wordDocuments, null);
                dataGridView1.AllowUserToAddRows = false;
                dataGridView1.AllowUserToDeleteRows = false;
                dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
                dataGridView1.RowHeadersVisible = false;
                dataGridView1.MultiSelect = false;
                dataGridView1.ReadOnly = false;

                // 注册表头点击事件
                dataGridView1.ColumnHeaderMouseClick -= DataGridView1_ColumnHeaderMouseClick;
                dataGridView1.ColumnHeaderMouseClick += DataGridView1_ColumnHeaderMouseClick;
            }
            catch (Exception ex)
            {
                MessageBox.Show($"初始化数据表格时发生错误：{ex.Message}",
                               "错误",
                               MessageBoxButtons.OK,
                               MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 处理表头点击事件
        /// 实现全选/取消全选功能
        /// </summary>
        private void DataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.ColumnIndex == dataGridView1.Columns["IsSelected"].Index)
            {
                var headerCell = dataGridView1.Columns["IsSelected"].HeaderCell as DataGridViewCheckBoxHeaderCell;
                if (headerCell != null)
                {
                    // 切换复选框状态
                    headerCell.Checked = !headerCell.Checked;

                    // 更新所有行的复选框状态
                    foreach (var doc in m_wordDocuments)
                    {
                        doc.IsSelected = headerCell.Checked;
                    }

                    // 刷新表格显示
                    dataGridView1.InvalidateColumn(e.ColumnIndex);
                    dataGridView1.RefreshEdit();
                }
            }
        }

        /// <summary>
        /// 获取Word文档的页数
        /// 使用OpenXML SDK读取文档属性
        /// </summary>
        /// <param name="filePath">文档路径</param>
        /// <returns>文档页数</returns>
        private int GetWordDocumentPageCount(string filePath)
        {
            try
            {
                using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(filePath, false))
                {
                    var extendedFileProperties = wordDoc.ExtendedFilePropertiesPart.Properties;
                    var pageCount = extendedFileProperties.Elements<DocumentFormat.OpenXml.ExtendedProperties.Pages>().FirstOrDefault();
                    return pageCount != null ? int.Parse(pageCount.Text) : 0;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"获取文档页数时出错：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return 0;
            }
        }

        /// <summary>
        /// 处理单元格点击事件
        /// 处理复选框状态变化、预览和删除按钮点击
        /// </summary>
        private void DataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex < 0) return;

            try
            {
                // 处理复选框点击
                if (e.ColumnIndex == dataGridView1.Columns["IsSelected"].Index)
                {
                    m_wordDocuments[e.RowIndex].IsSelected = !m_wordDocuments[e.RowIndex].IsSelected;

                    // 检查是否所有行都被选中
                    bool allSelected = m_wordDocuments.All(doc => doc.IsSelected);
                    var headerCell = dataGridView1.Columns["IsSelected"].HeaderCell as DataGridViewCheckBoxHeaderCell;
                    if (headerCell != null)
                    {
                        headerCell.Checked = allSelected;
                        dataGridView1.InvalidateColumn(e.ColumnIndex);
                    }
                    return;
                }

                // 处理预览按钮点击
                if (e.ColumnIndex == dataGridView1.Columns["preview"].Index)
                {
                    string filePath = m_wordDocuments[e.RowIndex].FullPath;
                    PreviewWordDocument(filePath);
                }
                // 处理删除按钮点击
                else if (e.ColumnIndex == dataGridView1.Columns["delete"].Index)
                {
                    var doc = m_wordDocuments[e.RowIndex];
                    if (MessageBox.Show($"确定要删除条目(不会删除本地文档)： {doc.FileName} 吗？",
                                      "确认删除",
                                      MessageBoxButtons.YesNo,
                                      MessageBoxIcon.Question) == DialogResult.Yes)
                    {
                        m_wordDocuments.RemoveAt(e.RowIndex);
                        dataGridView1.DataSource = new BindingSource(m_wordDocuments, null);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"操作失败：{ex.Message}",
                               "错误",
                               MessageBoxButtons.OK,
                               MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 预览Word文档
        /// 使用系统默认程序打开文档
        /// </summary>
        /// <param name="filePath">文档路径</param>
        private void PreviewWordDocument(string filePath)
        {
            try
            {
                if (!File.Exists(filePath))
                {
                    MessageBox.Show("文件不存在！",
                                  "错误",
                                  MessageBoxButtons.OK,
                                  MessageBoxIcon.Error);
                    return;
                }

                System.Diagnostics.Process.Start(filePath);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"预览文档时出错：{ex.Message}",
                               "错误",
                               MessageBoxButtons.OK,
                               MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 打开当前选中的模板
        /// 使用系统默认程序打开模板文件
        /// </summary>
        private void button5_Click(object sender, EventArgs e)
        {
            try
            {
                if (m_comboBox1.SelectedItem == null)
                {
                    MessageBox.Show("请先选择一个模板！",
                                  "提示",
                                  MessageBoxButtons.OK,
                                  MessageBoxIcon.Information);
                    return;
                }

                string selectedFileName = m_comboBox1.SelectedItem.ToString();
                if (templatePathMap.TryGetValue(selectedFileName, out string templatePath))
                {
                    if (!File.Exists(templatePath))
                    {
                        MessageBox.Show($"模板文件不存在：{templatePath}",
                                      "错误",
                                      MessageBoxButtons.OK,
                                      MessageBoxIcon.Error);
                        return;
                    }

                    System.Diagnostics.Process.Start(templatePath);
                }
                else
                {
                    MessageBox.Show($"无法获取模板文件路径：{selectedFileName}",
                                  "错误",
                                  MessageBoxButtons.OK,
                                  MessageBoxIcon.Error);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"打开模板时发生错误：{ex.Message}",
                               "错误",
                               MessageBoxButtons.OK,
                               MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 删除当前选中的模板
        /// 从列表中移除模板（不删除本地文件）
        /// </summary>
        private void button6_Click(object sender, EventArgs e)
        {
            try
            {
                if (m_comboBox1.SelectedItem == null)
                {
                    MessageBox.Show("请先选择要删除的模板！",
                                  "提示",
                                  MessageBoxButtons.OK,
                                  MessageBoxIcon.Information);
                    return;
                }

                string selectedFileName = m_comboBox1.SelectedItem.ToString();

                if (MessageBox.Show($"确定要删除模板 {selectedFileName} 吗？\n(不会删除本地文件)",
                                  "确认删除",
                                  MessageBoxButtons.YesNo,
                                  MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    templatePathMap.Remove(selectedFileName);
                    m_comboBox1.Items.Remove(selectedFileName);

                    if (m_comboBox1.Items.Count > 0)
                    {
                        m_comboBox1.SelectedIndex = 0;
                    }
                    else
                    {
                        m_comboBox1.SelectedIndex = -1;
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"删除模板时发生错误：{ex.Message}",
                               "错误",
                               MessageBoxButtons.OK,
                               MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 合并文档按钮点击事件处理
        /// 将选中的文档按照模板格式合并成一个新文档
        /// </summary>
        private void button3_Click(object sender, EventArgs e)
        {
            try
            {
                // 1. 检查是否选择了模板和文档
                if (m_comboBox1.SelectedItem == null)
                {
                    MessageBox.Show("请先选择一个模板文件！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                var selectedDocs = m_wordDocuments.Where(doc => doc.IsSelected).ToList();
                if (!selectedDocs.Any())
                {
                    MessageBox.Show("请先选择要合并的文档！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                // 2. 获取选中的模板文件路径
                string templateFileName = m_comboBox1.SelectedItem.ToString();
                string templatePath = templatePathMap[templateFileName];

                // 3. 创建保存对话框
                using (SaveFileDialog saveDialog = new SaveFileDialog())
                {
                    saveDialog.Filter = "Word文档(*.docx)|*.docx";
                    saveDialog.Title = "保存合并后的文档";
                    saveDialog.DefaultExt = "docx";
                    saveDialog.AddExtension = true;
                    saveDialog.FileName = "格式归并.docx";

                    if (saveDialog.ShowDialog() == DialogResult.OK)
                    {
                        string targetPath = saveDialog.FileName;
                        var wordApp = Globals.ThisAddIn.Application;
                        object missing = System.Type.Missing;

                        try
                        {
                            // 打开模板文档并获取样式
                            var templateDoc = wordApp.Documents.Open(templatePath, ReadOnly: true);
                            var templateStyles = new Dictionary<string, Microsoft.Office.Interop.Word.Style>();
                            
                            // 存储模板中的样式信息
                            foreach (Microsoft.Office.Interop.Word.Style style in templateDoc.Styles)
                            {
                                try
                                {
                                    if (style.NameLocal.StartsWith("标题") || style.NameLocal == "正文")
                                    {
                                        templateStyles[style.NameLocal] = style;
                                    }
                                }
                                catch { }
                            }

                            // 创建新文档并基于模板
                            object template = templatePath;
                            var mergedDoc = wordApp.Documents.Add(ref template);
                            templateDoc.Close();

                            // 合并所有选中的文档
                            foreach (var docInfo in selectedDocs)
                            {
                                // 插入分节符
                                if (mergedDoc.Words.Count > 1)
                                {
                                    mergedDoc.Words.Last.InsertBreak(Microsoft.Office.Interop.Word.WdBreakType.wdSectionBreakNextPage);
                                }

                                // 打开并复制源文档内容
                                var sourceDoc = wordApp.Documents.Open(docInfo.FullPath, ReadOnly: true);
                                sourceDoc.Content.Copy();
                                mergedDoc.Words.Last.Paste();

                                // 应用模板格式到新插入的内容
                                var lastSection = mergedDoc.Sections.Last;
                                foreach (Microsoft.Office.Interop.Word.Paragraph para in lastSection.Range.Paragraphs)
                                {
                                    try
                                    {
                                        // 获取并应用样式
                                        string currentStyleName = para.get_Style().NameLocal;
                                        object styleName = currentStyleName.StartsWith("标题") ? currentStyleName : "正文";

                                        if (templateStyles.ContainsKey(styleName.ToString()))
                                        {
                                            // 应用完整格式（样式、字体、段落格式）
                                            var templateStyle = templateStyles[styleName.ToString()];
                                            para.set_Style(ref styleName);
                                            para.Range.Font.Size = templateStyle.Font.Size;
                                            para.Range.Font.Name = templateStyle.Font.Name;
                                            para.Format.LineSpacing = templateStyle.ParagraphFormat.LineSpacing;
                                            para.Format.SpaceBefore = templateStyle.ParagraphFormat.SpaceBefore;
                                            para.Format.SpaceAfter = templateStyle.ParagraphFormat.SpaceAfter;
                                            para.Format.FirstLineIndent = templateStyle.ParagraphFormat.FirstLineIndent;
                                        }
                                    }
                                    catch
                                    {
                                        continue; // 如果应用格式失败，继续处理下一段
                                    }
                                }

                                sourceDoc.Close();
                            }

                            // 保存并关闭合并后的文档
                            mergedDoc.SaveAs2(targetPath);
                            mergedDoc.Close();

                            MessageBox.Show("文档合并完成！", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show($"合并文档时发生错误：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                        finally
                        {
                            // 清理未关闭的文档
                            foreach (Microsoft.Office.Interop.Word.Document doc in wordApp.Documents)
                            {
                                try
                                {
                                    doc.Close(SaveChanges: false);
                                }
                                catch { }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"操作发生错误：{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }
}
